/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package agency.tango.materialintroscreen.interceptor;

import java.io.IOException;

import ohos.agp.components.AttrSet;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import ohos.global.resource.solidxml.Theme;

import agency.tango.materialintroscreen.AttrString;
import agency.tango.materialintroscreen.utils.LogUtil;
import agency.tango.materialintroscreen.ResourceTable;

/**
 * @ProjectName: material-intro-screen-master
 * @Package: agency.tango.materialintroscreen.interceptor
 * @ClassName: CycleInterpolator
 * @Description: Repeats the animation for a specified number of cycles. The
 * rate of change follows a sinusoidal pattern.
 * @CreateDate: 2021/4/12 16:18
 * @UpdateDate: 2021/4/12 16:18
 * @UpdateRemark: 暂无
 * @Version: 1.0
 */
public class CycleInterpolator extends BaseInterpolator {
    private float mCycles;

    /**
     * Constructor
     *
     * @param cycles 往复运动次数
     */
    public CycleInterpolator(float cycles) {
        this(null, null);
        mCycles = cycles;
    }

    /**
     * Constructor
     *
     * @param context 上下文
     * @param attrs   属性集
     */
    public CycleInterpolator(Context context, AttrSet attrs) {
        this(context == null ? null : context.getResourceManager(),
                context == null ? null : context.getTheme(), attrs);
    }

    /**
     * Constructor
     *
     * @param resources 资源管理器
     * @param theme     主题
     * @param attrs     属性集
     */
    public CycleInterpolator(ResourceManager resources, Theme theme, AttrSet attrs) {
        try {
            if (attrs != null && attrs.getAttr(AttrString.CYCLEINTERPOLATORCYCLES).isPresent()) {
                mCycles =
                        attrs.getAttr(AttrString.CYCLEINTERPOLATORCYCLES).isPresent() ?
                                attrs.getAttr(AttrString.CYCLEINTERPOLATORCYCLES).get().getIntegerValue() :
                                1;
            } else if (resources != null
                    && resources.getElement(ResourceTable.Integer_cycleInterpolatorCycles) != null) {
                mCycles =
                        resources.getElement(ResourceTable.Integer_cycleInterpolatorCycles).getInteger();
            } else {
                mCycles = 1;
            }
            setChangingConfiguration(0);
        } catch (NotExistException | WrongTypeException | IOException e) {
            LogUtil.error(this.getClass().getSimpleName(), e.toString());
        }
    }

    /**
     * 把0到1的elapsed fraction变化映射到另一个interpolated
     * fraction。传入参数是正常执行动画的时间点，返回值是用户真正想要它执行的时间点。
     *
     * @param input A value between 0 and 1.0 indicating our current point
     *              in the animation where 0 represents the start and 1.0
     *              represents
     *              the end
     * @return 改变之后的时间值
     */
    public float getInterpolation(float input) {
        return getCurvedTime(input);
    }

    /**
     * 将标准化时间改变为到特定曲线
     *
     * @param input 输入时间
     * @return 正弦曲线波动的时间值
     */
    @Override
    public float getCurvedTime(float input) {
        return (float) (Math.sin(2 * mCycles * Math.PI * input));
    }
}

